using CefSharp;
//using CefSharp.DevTools.FedCm;
using System.Net.Http.Headers;
using System.Runtime.Caching;
using Web_rongmeiti_sys.Model;

namespace Web_rongmeiti_sys.PublishToRongMeiTi
{
    /// <summary>
    /// 发布文章到甲甲，sharepoint2.0
    /// </summary>
    /// 创建时间：2023-5-26 15:50:35。作者：whl
    public class ArticlePublishHandler
    {
        /// <summary>
        /// 发送超时时间，单位【秒】
        /// </summary>
        const int SendTimeOutSeconds = 33;

        /// <summary>
        ///  文章已经发布成功事件
        /// </summary>
        public static event EventHandler<Web_rongmeiti_sys.Model.Article> PublishArticleSuccessed;


        /// <summary>
        /// 用户信息保存到文件中
        /// </summary>
        /// <param name="json"></param>
        /// 创建时间：2023-5-29 15:03:39。作者：whl
        public static void SaveUserInfoToDiskFile(string json, string cnpc_account)
        {
            string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "identity_user_json");
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            string file = Path.Combine(dir, cnpc_account + ".txt");
            File.WriteAllText(file, json);
        }

        /// <summary>
        /// 读取用户信息 
        /// </summary>
        /// <param name="cnpc_account"></param>
        /// 创建时间：2023-6-19 10:00:34。作者：whl
        public static GetCurrentUserInfo GetUserInfo(string cnpc_account)
        {
            string cacheKey = "userinfo" + cnpc_account;
            var userCache = System.Runtime.Caching.MemoryCache.Default.Get(cacheKey) as GetCurrentUserInfo;
            if (userCache != null)
            {
                LogHelpter.AddLog("GetUserInfo命中缓存，cnpc_account=" + cnpc_account, null, "GetUserInfo");
                return userCache;
            }
            //读取用户信息
            string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "identity_user_json");
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            string file = Path.Combine(dir, cnpc_account + ".txt");
            if (System.IO.File.Exists(file))
            {
                //如果用户本地信息文件已经超过20天没有更新了，则从新请求用户信息
                DateTime lastWriteTime = File.GetLastWriteTime(file);
                if ((DateTime.Now - lastWriteTime).TotalHours > 480)
                {
                    goto UPDATE_USER_INFO;
                }

                string json = File.ReadAllText(file);
                var userInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<GetCurrentUserInfo>(json);

                //滑动过期，十天有效              
                System.Runtime.Caching.MemoryCache.Default.Set(cacheKey, userInfo, new CacheItemPolicy() { SlidingExpiration = TimeSpan.FromMinutes(14400) });
                return userInfo;
            }

        UPDATE_USER_INFO:
            //如果没有用户信息文件，则主动请求用户信息
            string? identityCookie = AuthCookieHelpter.GetIdentityCookie(cnpc_account);
            if (string.IsNullOrWhiteSpace(identityCookie))
            {
                //throw new Exception("用户没有登录，没有获取到IdentityCookie");
                LogHelpter.AddLog($"用户{cnpc_account}没有登录，没有获取到IdentityCookie", null, "GetUserInfo");
                return null;
            }
            string userJson = "";
            try
            {
                //请求用户信息
                string url = MyConfigReader.GetConfigValue("url_get_user_info");
                HttpClient httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromSeconds(20);
                httpClient.DefaultRequestHeaders.Add("Cookie", identityCookie);
                var task = httpClient.GetStringAsync(url);
                task.Wait();
                userJson = task.Result;
            }
            catch (Exception ex)
            {
                LogHelpter.AddLog("获取登录用户信息失败，", null, "GetUserInfo_error");
                return null;
            }

            var userInfo2 = Newtonsoft.Json.JsonConvert.DeserializeObject<GetCurrentUserInfo>(userJson);
            if (!userInfo2.result.accountName.Equals(cnpc_account))
            {
                LogHelpter.AddLog($"获取用户信息账号{userInfo2.result.accountName}与传入参数cnpc_account={cnpc_account}不匹配，", null, "GetUserInfo_error");
                return null;
            }
            File.WriteAllText(file, userJson);

            //滑动过期，十天有效              
            System.Runtime.Caching.MemoryCache.Default.Set(cacheKey, userInfo2, new CacheItemPolicy() { SlidingExpiration = TimeSpan.FromMinutes(14400) });
            return userInfo2;
        }

        /// <summary>
        /// 发布文章到甲甲 
        /// </summary>
        /// <param name="article"></param>
        /// <returns></returns>
        /// 创建时间：2023-5-26 15:54:37。作者：whl
        public static async Task<Result> PublishArticle(Web_rongmeiti_sys.Model.Article article)
        {
        Get_user_info:
            GetCurrentUserInfo publishUser = GetUserInfo(article.Cnpc_account);
            if (publishUser == null || publishUser.result == null)
            {
                //return new Result("发布人信息没有获取到，请检查");

                //重新登录，获取身份信息，获取cookie的值
                LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                goto Get_user_info;
            }
            ushort errorCount = 0;

        AGAIN_PUBLISH:

            //获取身份信息，获取cookie的值
            string? identityCookie = AuthCookieHelpter.GetIdentityCookie(article.Cnpc_account);
            if (string.IsNullOrWhiteSpace(identityCookie))
            {
                //重新登录，获取身份信息，获取cookie的值
                LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                goto AGAIN_PUBLISH;
            }
            string html = article.HtmlContent;

            LogHelpter.AddLog($"文章id={article.ArticleId},收到的文章html={html}", null, "orgHtml");

            //处理html格式，处理甲甲图片左侧空白，2023-7-12 18:29:51
            html = MyHtmlHelper.HtmlCheck(html);

            //文章内容中图片、文件上传到甲甲平台中
            var fileDictResult = await ArticleContentFileFilterHandler.HtmlImgOrFileFilter(html, article );
            if (fileDictResult.Code != 200)
            {
                return new Result(fileDictResult.Msg);
            }
            if (fileDictResult.Data != null && fileDictResult.Data.Count > 0)
            {
                foreach (var fileUrlKv in fileDictResult.Data)
                {
                    html = html.Replace(fileUrlKv.Key, fileUrlKv.Value);
                }
            }

            //publishingStartDate: "2023-05-26T17:17"
            //测试发现甲甲服务器时间快了8分钟，影响了计划时间精准
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                //notes="",
                newsLayoutPage = "C_NewAutoTitle_2019.aspx",
                publishingContactName = publishUser.result.displayName, /*发布人姓名*/
                publishingContactEmail = publishUser.result.email,
                publishingContactPhone = publishUser.result.mobile,
                orgCode = publishUser.result.orgCode,

                publishingStartDate = article.PlanPublishingStartDate,  /*计划发布时间*/
                publishingExpirationDate = article.Plan_removal_time,   /*  计划结束时间2023-07-17T14:10 */
                newsNum = "whl_" + article.ArticleId,
                subTitle = $"<p style=\"line-height: 30px; text-align: center;\"><span style=\"font-family: 'Microsoft YaHei', 'Helvetica Neue', 'PingFang SC', sans-serif; font-size: 30px; color: #222222; font-weight: bold;\">{article.Title}</span></p>",
                publishingPageContent = html,
                headTitle = article.Title,

                //Recommends=new object[1] ,
                //NewsKeyword="",

                IsSecret = true,
                columnID = article.ColumnID,
                newsType = 1,
                newsStatus = 1,
                isPublishing = true
            });

        Send_two:
            HttpClient httpClient = new HttpClient();
            httpClient.Timeout = TimeSpan.FromSeconds(SendTimeOutSeconds);

            HttpContent httpContent = new StringContent(json);
            httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" };

            httpClient.DefaultRequestHeaders.Add("Referer", MyConfigReader.GetConfigValue("rongmeiti_url"));
            httpClient.DefaultRequestHeaders.Add("userSelectOrgCode", publishUser.result.orgCode);
            httpClient.DefaultRequestHeaders.Add("Origin", MyConfigReader.GetConfigValue("rongmeiti_url"));
            httpClient.DefaultRequestHeaders.Add("Cookie", identityCookie);

            HttpResponseMessage responseMessage =
                  await httpClient.PostAsync(MyConfigReader.GetConfigValue("publish_article_to_sharepoint_url"), httpContent);
            string resultJson = await responseMessage.Content.ReadAsStringAsync();

            LogHelpter.AddLog("发布文章，o_Id=" + article.ArticleId + $",StatusCode={(int)responseMessage.StatusCode},ReasonPhrase={responseMessage.ReasonPhrase}，甲甲返回：" + resultJson, null, "PublishArticle");

            ResultNews resultNews = new ResultNews();
            bool right = responseMessage.StatusCode == System.Net.HttpStatusCode.OK;
            int statusCode = (int)responseMessage.StatusCode;

            if (responseMessage.StatusCode == System.Net.HttpStatusCode.Unauthorized)
            {
                LogHelpter.AddLog("发布文章" + article.ArticleId + "，甲甲报401" + resultJson, null, "ArticlePublishHandler_PublishArticle_error");

                //错误次数累计
                errorCount++;
                if (errorCount > 2)
                {
                    return new Result("发布失败，甲甲报401，没有获取到身份信息，请联系管理员");
                }

                //重新登录，获取身份信息，获取cookie的值
                var loginResult = LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                if (loginResult.Code != 200)
                {
                    return new Result(loginResult.Msg);
                }
                httpClient.Dispose();
                responseMessage.Dispose();

                //获取身份 cookie
                identityCookie = AuthCookieHelpter.GetIdentityCookie(article.Cnpc_account);

                goto Send_two;
            }
            if (JudgeStatusCode(statusCode))
            {
                goto Req_done;/* 处理完成 */
            }

            /*  甲甲返回josn
{
    "code": 200,
    "message": "",
    "result": 3
}
             */

            resultNews = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultNews>(resultJson);
            if (right)
            {
                if (resultNews.code == 200)
                {
                    //文章发布成功，通知
                    PublishArticleSuccessed?.Invoke(null, article);

                    return new Result("发布成功", 200);
                }
                else
                {
                    return new Result($"发布出错,{resultNews.message}");
                }
            }
        Req_done:
            //修改了返回消息，修改时间：2023-8-30 10:23:53
            //return new Result($"发布失败,statusCode={statusCode}," + (resultNews.message ?? responseMessage.ReasonPhrase));
            return new Result($"发布失败,statusCode={statusCode},甲甲返回:{resultJson}");
        }

        /// <summary>
        /// 发布引用链接文章
        /// </summary>
        /// <param name="article">文章信息</param>
        /// <returns></returns>
        /// <remarks>
        /// 创建时间：2023-7-14 17:31:17，作者：whl
        /// </remarks>
        public static async Task<Result> PublishReferenceLinkArticle(Article article)
        {
        Get_user_info:
            GetCurrentUserInfo publishUser = GetUserInfo(article.Cnpc_account);
            if (publishUser == null || publishUser.result == null)
            {
                //return new Result("发布人信息没有获取到，请检查");

                //重新登录，获取身份信息，获取cookie的值
                LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                goto Get_user_info;
            }
            ushort errorCount = 0;

        AGAIN_PUBLISH:

            //获取身份信息，获取cookie的值
            string? identityCookie = AuthCookieHelpter.GetIdentityCookie(article.Cnpc_account);
            if (string.IsNullOrWhiteSpace(identityCookie))
            {
                //重新登录，获取身份信息，获取cookie的值
                LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                goto AGAIN_PUBLISH;
            }
            LogHelpter.AddLog($"文章id={article.ArticleId},收到的文章RedirectURL={article.RedirectURL}", null, "RedirectURL");

            //publishingStartDate: "2023-05-26T17:17"
            //测试发现甲甲服务器时间快了8分钟，影响了计划时间精准
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                //notes="",
                newsLayoutPage = "C_Redirect.aspx",
                publishingContactName = publishUser.result.displayName, /*发布人姓名*/
                publishingContactEmail = publishUser.result.email,
                publishingContactPhone = publishUser.result.mobile,
                orgCode = publishUser.result.orgCode,

                publishingStartDate = article.PlanPublishingStartDate,  /*计划发布时间*/
                publishingExpirationDate = article.Plan_removal_time,     /*计划结束时间*/
                newsNum = "whl_R_" + article.ArticleId,
                subTitle = $"<p style=\"line-height: 30px; text-align: center;\"><span style=\"font-family: 'Microsoft YaHei', 'Helvetica Neue', 'PingFang SC', sans-serif; font-size: 30px; color: #222222; font-weight: bold;\">{article.Title}</span></p>",
                //headStyle = "",
                headTitle = article.Title,
                redirectURL = article.RedirectURL,
                publishingPageContent = "引用新闻",

                columnID = article.ColumnID,
                IsSecret = true,
                newsType = 2,  /* 引用新闻 */
                newsStatus = 1,
                isPublishing = true
            });

        Send_two:
            HttpClient httpClient = new HttpClient();
            httpClient.Timeout = TimeSpan.FromSeconds(SendTimeOutSeconds);

            HttpContent httpContent = new StringContent(json);
            httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" };

            //httpClient.DefaultRequestHeaders.Add("Referer", MyConfigReader.GetConfigValue("rongmeiti_url"));
            //httpClient.DefaultRequestHeaders.Add("Origin", MyConfigReader.GetConfigValue("rongmeiti_url"));
            httpClient.DefaultRequestHeaders.Add("userSelectOrgCode", publishUser.result.orgCode);
            httpClient.DefaultRequestHeaders.Add("Cookie", identityCookie);

            HttpResponseMessage responseMessage =
                  await httpClient.PostAsync(MyConfigReader.GetConfigValue("publish_article_to_sharepoint_url"), httpContent);
            string resultJson = await responseMessage.Content.ReadAsStringAsync();
            LogHelpter.AddLog("发布引用文章，o_Id=" + article.ArticleId + $",StatusCode={(int)responseMessage.StatusCode},ReasonPhrase={responseMessage.ReasonPhrase}，甲甲返回：" + resultJson, null, "PublishArticleRedirect");

            ResultNews resultNews = new ResultNews();
            bool right = responseMessage.StatusCode == System.Net.HttpStatusCode.OK;
            int statusCode = (int)responseMessage.StatusCode;

            if (responseMessage.StatusCode == System.Net.HttpStatusCode.Unauthorized)
            {
                LogHelpter.AddLog("发布引用文章" + article.ArticleId + "，甲甲报401" + resultJson, null, "PublishArticleRedirect_error");

                //错误次数累计
                errorCount++;
                if (errorCount > 2)
                {
                    return new Result("发布失败，甲甲报401，没有获取到身份信息，请联系管理员");
                }

                //重新登录，获取身份信息，获取cookie的值
                var loginResult = LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                if (loginResult.Code != 200)
                {
                    return new Result(loginResult.Msg);
                }

                //获取身份 cookie，添加时间：2023-8-3 15:42:41
                identityCookie = AuthCookieHelpter.GetIdentityCookie(article.Cnpc_account);

                goto Send_two;
            }
            if (JudgeStatusCode(statusCode))
            {
                goto Req_done;/* 处理完成 */
            }

            /*  甲甲返回josn
{
    "code": 200,
    "message": "",
    "result": 3
}
             */

            resultNews = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultNews>(resultJson);
            if (right)
            {
                if (resultNews.code == 200)
                {
                    //文章发布成功，通知
                    PublishArticleSuccessed?.Invoke(null, article);

                    return new Result("发布成功", 200);
                }
                else
                {
                    return new Result($"发布出错,{resultNews.message}");
                }
            }
        Req_done:            
            //修改了返回消息，修改时间：2023-8-30 10:23:53
            //return new Result($"发布失败,statusCode={statusCode}," + (resultNews.message ?? responseMessage.ReasonPhrase));
            return new Result($"发布失败,statusCode={statusCode},甲甲返回:{resultJson}");
        }

        /// <summary>
        /// 修改甲甲里面的文章， 
        /// </summary>
        /// <param name="article">文章数据</param>
        /// <param name="rongmetiArticleId">甲甲文章id</param>
        /// <returns></returns>
        /// 创建时间：2023-8-1 10:35:37，作者：whl
        public static async Task<Result> UpdateArticle(Article article, string rongmetiArticleId)
        {
        Get_user_info:
            GetCurrentUserInfo publishUser = GetUserInfo(article.Cnpc_account);
            if (publishUser == null || publishUser.result == null)
            {
                //return new Result("发布人信息没有获取到，请检查");

                //重新登录，获取身份信息，获取cookie的值
                LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                goto Get_user_info;
            }
            ushort errorCount = 0;

        AGAIN_PUBLISH:

            //获取身份信息，获取cookie的值
            string? identityCookie = AuthCookieHelpter.GetIdentityCookie(article.Cnpc_account);
            if (string.IsNullOrWhiteSpace(identityCookie))
            {
                //重新登录，获取身份信息，获取cookie的值
                LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                goto AGAIN_PUBLISH;
            }
            string html = article.HtmlContent;

            LogHelpter.AddLog($"文章id={article.ArticleId},收到的文章html={html}", null, "orgHtml");
            if (article.News_type == 2) /* 引用新闻 */
            {
                goto See_json;
            }

            //处理html格式，处理甲甲图片左侧空白，2023-7-12 18:29:51
            html = MyHtmlHelper.HtmlCheck(html);

            //文章内容中图片、文件上传到甲甲平台中
            var fileDictResult = await ArticleContentFileFilterHandler.HtmlImgOrFileFilter(html,article);
            if (fileDictResult.Code != 200)
            {
                return new Result(fileDictResult.Msg);
            }
            if (fileDictResult.Data != null && fileDictResult.Data.Count > 0)
            {
                foreach (var fileUrlKv in fileDictResult.Data)
                {
                    html = html.Replace(fileUrlKv.Key, fileUrlKv.Value);
                }
            }

        See_json:
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(
                new
                {
                    //表示【发布】的文章数据
                    tableType = "issue",
                    model =
                        new
                        {
                            id = rongmetiArticleId,       /* 甲甲文章id */

                            newsLayoutPage = article.News_type == 1 ? "C_NewAutoTitle_2019.aspx" : "C_Redirect.aspx",
                            publishingContactName = publishUser.result.displayName, /*发布人姓名*/
                            publishingContactEmail = publishUser.result.email,
                            publishingContactPhone = publishUser.result.mobile,
                            orgCode = publishUser.result.orgCode,

                            publishingStartDate = article.PlanPublishingStartDate,  /*计划发布时间*/
                            publishingExpirationDate = article.Plan_removal_time,   /*  计划结束时间2023-07-17T14:10 */
                            newsNum = article.News_type == 1 ? "whl_" + article.ArticleId : "whl_R_" + article.ArticleId,
                            subTitle = $"<p style=\"line-height: 30px; text-align: center;\"><span style=\"font-family: 'Microsoft YaHei', 'Helvetica Neue', 'PingFang SC', sans-serif; font-size: 30px; color: #222222; font-weight: bold;\">{article.Title}</span></p>",
                            publishingPageContent = html,
                            headTitle = article.Title,   /*  标题  */

                            IsSecret = true,
                            isPublishing = true,
                            isHiddenModePublished = false,

                            columnID = article.ColumnID,
                            newsType = article.News_type,  /*  1=图文，2=引用链接 */
                            newsStatus = 1,

                            redirectURL = article.RedirectURL,
                        }
                }
                );

        Send_two:
            HttpClient httpClient = new HttpClient();
            httpClient.Timeout = TimeSpan.FromSeconds(SendTimeOutSeconds);

            HttpContent httpContent = new StringContent(json);
            httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" };

            //httpClient.DefaultRequestHeaders.Add("Referer", MyConfigReader.GetConfigValue("rongmeiti_url"));
            //httpClient.DefaultRequestHeaders.Add("Origin", MyConfigReader.GetConfigValue("rongmeiti_url"));
            httpClient.DefaultRequestHeaders.Add("userSelectOrgCode", publishUser.result.orgCode);
            httpClient.DefaultRequestHeaders.Add("Cookie", identityCookie);

            HttpResponseMessage responseMessage =
                  await httpClient.PutAsync(MyConfigReader.GetConfigValue("pf_eip_update_url"), httpContent);
            string resultJson = await responseMessage.Content.ReadAsStringAsync();

            LogHelpter.AddLog("修改文章，o_Id=" + article.ArticleId + $",StatusCode={(int)responseMessage.StatusCode},ReasonPhrase={responseMessage.ReasonPhrase}，甲甲返回：" + resultJson + ",发送参数=" + json, null, "UpdateArticle");

            ResultNews resultNews = new ResultNews();
            bool right = responseMessage.StatusCode == System.Net.HttpStatusCode.OK;
            int statusCode = (int)responseMessage.StatusCode;

            if (responseMessage.StatusCode == System.Net.HttpStatusCode.Unauthorized)
            {
                LogHelpter.AddLog("修改文章" + article.ArticleId + "，甲甲报401" + resultJson, null, "UpdateArticle_error");

                //错误次数累计
                errorCount++;
                if (errorCount > 2)
                {
                    return new Result("修改文章，甲甲报401，没有获取到身份信息，请联系管理员");
                }

                //重新登录，获取身份信息，获取cookie的值
                var loginResult = LoginHandler.LoginCall(article.Cnpc_account, article.Cnpc_password);
                if (loginResult.Code != 200)
                {
                    return new Result(loginResult.Msg);
                }

                //获取身份 cookie，添加时间：2023-8-3 15:42:41
                identityCookie = AuthCookieHelpter.GetIdentityCookie(article.Cnpc_account);

                goto Send_two;
            }
            if (JudgeStatusCode(statusCode))
            {
                goto Req_done;/* 处理完成 */
            }

            resultNews = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultNews>(resultJson);
            if (right)
            {
                if (resultNews.code == 200)
                {
                    //文章修改成功，通知
                    PublishArticleSuccessed?.Invoke(null, article);

                    return new Result("修改成功", 200);
                }
                else
                {
                    return new Result($"修改出错,{resultNews.message}");
                }
            }
        Req_done:
            return new Result($"修改失败,statusCode={statusCode}," + (resultNews.message ?? responseMessage.ReasonPhrase));
        }

        /// <summary>
        /// (发布失败),判断响应状态值，返回布尔值
        /// </summary>
        /// <param name="statusCode"></param>
        /// <returns></returns>
        /// 创建时间：2023-8-1 14:33:43，作者：whl
        private static bool JudgeStatusCode(int statusCode)
        {
            return statusCode != 422
                && statusCode != 404
                && statusCode > 200 && statusCode < 500;
        }
    }
}
